package com.hibernate.fetch;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.junit.Test;

import com.hibernate.domain.Classes;
import com.hibernate.domain.Student;
import com.hibernate.utils.HibernateUtil;

/**
 * hibernate抓取策略测试类
 * @author LC
 *
 */
public class HibernateFetchTest extends HibernateUtil {
	
	/**
	 * 创造测试数据
	 */
	@Test
	public void createData() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = new Classes("1班", "培训1班") ;
		Student student01 = new Student("111","111");
		Student student02 = new Student("222","222");
		Student student03 = new Student("333","333");
		Student student04 = new Student("444","444");
		Student student05 = new Student("555","555");
		Student student06 = new Student("666","666");
		Set<Student> students = new HashSet<>() ;
		students.add(student01) ;
		students.add(student02) ;
		students.add(student03) ;
		students.add(student04) ;
		students.add(student05) ;
		students.add(student06) ;
		classes.setStudents(students) ;
		session.save(classes) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 延迟加载测试01
	 * 		类的延迟加载
	 */
	@Test
	public void testClassLazyLoad() {
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.load(Classes.class, 1L) ;
		System.out.println(classes.getDescription());
		session.close() ;
	}

	/**
	 * 延迟加载测试02
	 * 		集合的延迟加载
	 */
	@Test
	public void testCollectionLazyLoad() {
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.load(Classes.class, 1L) ;
		Set<Student> students = classes.getStudents() ;
		for (Student student : students) {
			System.out.println(student.getSname());
		}
		session.close() ;
	}
	
	/**
	 * 查询所有的班级的所有的学生
	 *    在Classes.hbm.xml文件中
	 *       set元素的fetch如果是默认值"select"
	 *         将会导致n+1条sql语句   n代表classes表的行数
	 *    通过分析，该例子中含有子查询，所以用"subselect"效率比较高
	 *       set元素的fetch是"subselect"
	 *            select
				        students0_.cid as cid0_1_,
				        students0_.sid as sid1_,
				        students0_.sid as sid1_0_,
				        students0_.name as name1_0_,
				        students0_.description as descript3_1_0_,
				        students0_.cid as cid1_0_ 
				    from
				        Student students0_ 
				    where
				        students0_.cid in (
				            select
				                classes0_.cid 
				            from
				                Classes classes0_
				        )
		如果函数子查询，则抓取策略用join,还是n+1条查询
	 */
	@Test
	public void testFetch_01() {
		Session session = sessionFactory.openSession() ;
		List<Classes> classes = session.createQuery("from Classes").list() ;
		for (Classes classes2 : classes) {
			Set<Student> students = classes2.getStudents();
			for (Student student : students) {
				System.out.println(student.getSname());
			}
		}
		session.close() ;
	}
	
	/**
	 * 查询cid为1的班级的所有的学生
	 *    因为需要不含子查询，所以这里不用子查询
	 *    在Classes.hbm.xml文件中
	 *       set元素的fetch属性可以使用join
	 *         select
			        classes0_.cid as cid0_1_,
			        classes0_.name as name0_1_,
			        classes0_.description as descript3_0_1_,
			        students1_.cid as cid0_3_,
			        students1_.sid as sid3_,
			        students1_.sid as sid1_0_,
			        students1_.name as name1_0_,
			        students1_.description as descript3_1_0_,
			        students1_.cid as cid1_0_ 
			    from
			        Classes classes0_ 
			    left outer join
			        Student students1_ 
			            on classes0_.cid=students1_.cid 
			    where
			        classes0_.cid=?
			  如果设置为"join",在session.get(Classes.class)的时候就把classes与student全部加载出来了
	 */
	@Test
	public void testFetch_02() {
		Session session = sessionFactory.openSession();
		Classes classes = (Classes)session.get(Classes.class, 1L);
		Set<Student> students = classes.getStudents();
		for (Student student : students) {
			System.out.println(student.getSname());
		}
	}
	
	/**
	 * 查询cid为2，3, 4，5的班级的学生
	 *   用子查询"subselect"效率比较高
	 */
	@Test
	public void testFetch_03() {
		Session session = sessionFactory.openSession() ;
		List<Classes> classes = session.createQuery("from Classes where cid in (1,2,3,4)").list() ;
		for (Classes classes2 : classes) {
			Set<Student> students = classes2.getStudents() ;
			for (Student student : students) {
				System.out.println(student.getSname());
			}
		}
		session.close() ;
	}
	
	

}
